import { globSync as globSyncPath } from 'glob'
import type { GlobOptions } from 'glob' // 导入 glob 的配置类型
import { getRelativePath } from './helper'
/**
 * glob 解析结果的类型定义
 */
export interface ParseGlobResult {
    /** 匹配到的文件原始路径（保留系统原生分隔符） */
    path: string
    /** 路径中 * 匹配的具体值（如组件名、模块名） */
    starValue: string | null
    /** 该路径对应的 glob 模式 */
    pattern: string
}

/**
 * 通用 glob 解析函数（TypeScript 版）
 * 支持单个模式（string）或多个模式（string[]），提取路径中 * 对应的值，兼容跨平台路径
 * @param globPatterns 单个 glob 模式或模式数组（每个模式需包含且仅包含一个 *）
 * @param options 配置项
 * @param options.unique 是否对结果去重（按路径），默认 true
 * @param options.globOptions 传递给 glob 的配置（如忽略目录、匹配深度等）
 * @returns 解析结果数组，包含路径、*对应值、匹配的模式
 */

export const globToRegex = function (globPattern: string) {
    const regexSource = globPattern
        // 移除开头的 ../ 或 ..\（处理相对路径前缀）
        .replace(/^(?:\.\.?(?:[\\/])?)+/, '')
        // 统一路径分隔符为正则可匹配的 [\\/]（兼容 Windows 和 POSIX）
        .replace(/[\\/]/g, '[\\\\/]')
        // 处理 {a,b,c} 格式，转换为 (a|b|c)（核心新增逻辑）
        .replace(/\{([^}]+)\}/g, (_, groupContent) => {
            // 分割逗号，处理可能的空格（如 { ts, tsx }），拼接为备选分组
            return `(${groupContent
                .split(',')
                .map((item) => item.trim())
                .join('|')})`
        })
        // 处理 * 通配符（匹配非路径分隔符的任意字符）
        .replace(/\*/g, '([^\\\\/]+)')
        // 转义 . （避免正则中 . 匹配任意字符）
        .replace(/[.]/g, '\\$&')

    return new RegExp(`^${regexSource}$`)
}

export type parseGlobOptions = {
    unique?: boolean
    globOptions?: GlobOptions
}
export function parseGlob(
    globPattern: string,
    ignore: string | string[] = [],
    options: parseGlobOptions = {}
): ParseGlobResult[] {
    // 解析配置项（设置默认值）
    const { unique = true, globOptions = {} } = options
    const results: ParseGlobResult[] = []
    // 验证模式中 * 的数量（必须且仅包含一个）
    const starCount = (globPattern.match(/\*/g) || []).length
    if (starCount === 0) {
        throw new Error(`glob 模式 "${globPattern}" 必须包含至少一个 *`)
    }
    if (starCount > 1) {
        throw new Error(`glob 模式 "${globPattern}" 只能包含一个 *（当前有 ${starCount} 个）`)
    }
    // 生成匹配 * 的正则（兼容 Windows(\) 和 macOS(/）的路径分隔符）

    const starRegex = globToRegex(globPattern)
    // 用 glob 匹配文件路径（传入用户配置）
    const ignorePatterns = Array.isArray(ignore) ? ignore : [ignore]
    const filePaths = globSyncPath(globPattern, {
        ignore: ['**/node_modules/**', ...ignorePatterns],
        ...globOptions
    })
    if (Array.isArray(filePaths) && filePaths.length) {
        // 提取每个路径中 * 对应的值，添加到结果
        filePaths.forEach((filePath: any) => {
            const match = getRelativePath(filePath).match(starRegex)
            results.push({
                path: filePath,
                starValue: match?.[1] ?? null, // 用可选链和空值合并处理匹配失败的情况
                pattern: globPattern
            })
        })
    }

    // 去重处理（按 path 字段）
    if (unique) {
        const seenPaths = new Set<string>()
        return results.filter((item) => {
            if (seenPaths.has(item.path)) return false
            seenPaths.add(item.path)
            return true
        })
    }

    return results
}
